use actix_web::web::{Data, Json, Query};

use crate::{
    common::{
        app::tags::ROLE,
        types::{ApiListResult, ApiResult},
    },
    config::{auth::AuthInfo, state::AppState},
    models::{
        request::{
            common_request::IdRequest,
            role_req::{RoleBind, RoleCreate, RoleUpdate},
        },
        response::role_res::{RoleDetail, RoleList},
    },
    services::role_service as RoleService,
};

/// 新增角色
#[utoipa::path(
    tags = [ROLE],
    post,
    path = "/api/v1/role/create",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = RoleCreate
)]
pub async fn create(
    state: Data<AppState>,
    req: Json<RoleCreate>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    RoleService::create(state, req.into_inner(), auth_info).await
}

/// 删除角色
#[utoipa::path(
    tags = [ROLE],
    post,
    path = "/api/v1/role/delete",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn delete(
    state: Data<AppState>,
    req: Json<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    RoleService::delete(state, req.into_inner(), auth_info).await
}

/// 修改角色
#[utoipa::path(
    tags = [ROLE],
    post,
    path = "/api/v1/role/update",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = RoleUpdate
)]
pub async fn update(
    state: Data<AppState>,
    req: Json<RoleUpdate>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    RoleService::update(state, req.into_inner(), auth_info).await
}

/// 角色详情
#[utoipa::path(
    tags = [ROLE],
    get,
    path = "/api/v1/role/detail",
    responses(
        (status = 200, description = "Ok", body = RoleDetail),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = IdRequest
)]
pub async fn detail(
    state: Data<AppState>,
    req: Query<IdRequest>,
    auth_info: AuthInfo,
) -> ApiResult<RoleDetail> {
    RoleService::detail(state, req.into_inner(), auth_info).await
}

/// 角色列表
#[utoipa::path(
    tags = [ROLE],
    get,
    path = "/api/v1/role/list",
    responses(
        (status = 200, description = "Ok", body = RoleList),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
)]
pub async fn list(state: Data<AppState>, auth_info: AuthInfo) -> ApiListResult<RoleList> {
    RoleService::list(state, auth_info).await
}

/// 角色绑定
#[utoipa::path(
    tags = [ROLE],
    post,
    path = "/api/v1/role/bind",
    responses(
        (status = 200, description = "Ok", body = bool),
        (status = 400, description = "Bad Request"),
        (status = 401, description = "Unauthorized"),
        (status = 500, description = "Internal Server Error")
    ),
    request_body = RoleBind
)]
pub async fn bind(
    state: Data<AppState>,
    req: Json<RoleBind>,
    auth_info: AuthInfo,
) -> ApiResult<bool> {
    RoleService::bind(state, req.into_inner(), auth_info).await
}
